package com.example.performance.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 测试统计报告模型
 * 收集和汇总所有请求的执行结果统计信息
 */
public class TestReport {

    private String testName; // 测试名称
    private long testStartTime; // 测试开始时间
    private long testEndTime; // 测试结束时间
    private long testDuration; // 测试持续时间（毫秒）

    // 基础统计信息
    private int totalRequests; // 总请求数
    private int successRequests; // 成功请求数
    private int failedRequests; // 失败请求数
    private double successRate; // 成功率（百分比）

    // 响应时间统计
    private long minResponseTime; // 最小响应时间
    private long maxResponseTime; // 最大响应时间
    private double avgResponseTime; // 平均响应时间
    private long p95ResponseTime; // 95%分位响应时间
    private long p99ResponseTime; // 99%分位响应时间

    // QPS统计
    private double qps; // 每秒请求数
    private double tps; // 每秒成功事务数

    // 错误统计
    private Map<String, Integer> errorStats = new ConcurrentHashMap<>(); // 错误统计
    private Map<Integer, Integer> statusCodeStats = new ConcurrentHashMap<>(); // 状态码统计

    // 详细结果列表
    private List<RequestResult> results = new ArrayList<>();

    // 构造函数
    public TestReport() {
    }

    public TestReport(String testName) {
        this.testName = testName;
        this.testStartTime = System.currentTimeMillis();
    }

    // Getter和Setter方法
    public String getTestName() {
        return testName;
    }

    public void setTestName(String testName) {
        this.testName = testName;
    }

    public long getTestStartTime() {
        return testStartTime;
    }

    public void setTestStartTime(long testStartTime) {
        this.testStartTime = testStartTime;
    }

    public long getTestEndTime() {
        return testEndTime;
    }

    public void setTestEndTime(long testEndTime) {
        this.testEndTime = testEndTime;
        this.testDuration = testEndTime - testStartTime;
    }

    public long getTestDuration() {
        return testDuration;
    }

    public int getTotalRequests() {
        return totalRequests;
    }

    public int getSuccessRequests() {
        return successRequests;
    }

    public int getFailedRequests() {
        return failedRequests;
    }

    public double getSuccessRate() {
        return successRate;
    }

    public long getMinResponseTime() {
        return minResponseTime;
    }

    public long getMaxResponseTime() {
        return maxResponseTime;
    }

    public double getAvgResponseTime() {
        return avgResponseTime;
    }

    public long getP95ResponseTime() {
        return p95ResponseTime;
    }

    public long getP99ResponseTime() {
        return p99ResponseTime;
    }

    public double getQps() {
        return qps;
    }

    public double getTps() {
        return tps;
    }

    public Map<String, Integer> getErrorStats() {
        return errorStats;
    }

    public Map<Integer, Integer> getStatusCodeStats() {
        return statusCodeStats;
    }

    public List<RequestResult> getResults() {
        return results;
    }

    /**
     * 添加请求结果
     * 
     * @param result 请求结果
     */
    public void addResult(RequestResult result) {
        synchronized (this) {
            results.add(result);
            updateStatistics(result);
        }
    }

    /**
     * 更新统计信息
     * 
     * @param result 新的请求结果
     */
    private void updateStatistics(RequestResult result) {
        totalRequests++;

        if (result.isSuccess()) {
            successRequests++;
        } else {
            failedRequests++;
            // 统计错误信息
            String error = result.getErrorMessage();
            if (error != null) {
                errorStats.put(error, errorStats.getOrDefault(error, 0) + 1);
            }
        }

        // 统计状态码
        if (result.getStatusCode() > 0) {
            statusCodeStats.put(result.getStatusCode(),
                    statusCodeStats.getOrDefault(result.getStatusCode(), 0) + 1);
        }

        // 更新响应时间统计
        updateResponseTimeStats();

        // 计算成功率
        successRate = totalRequests > 0 ? (double) successRequests / totalRequests * 100 : 0;
    }

    /**
     * 更新响应时间统计
     */
    private void updateResponseTimeStats() {
        if (results.isEmpty())
            return;

        List<Long> responseTimes = new ArrayList<>();
        long sum = 0;
        minResponseTime = Long.MAX_VALUE;
        maxResponseTime = Long.MIN_VALUE;

        for (RequestResult result : results) {
            long responseTime = result.getResponseTime();
            responseTimes.add(responseTime);
            sum += responseTime;

            if (responseTime < minResponseTime) {
                minResponseTime = responseTime;
            }
            if (responseTime > maxResponseTime) {
                maxResponseTime = responseTime;
            }
        }

        // 计算平均响应时间
        avgResponseTime = (double) sum / results.size();

        // 计算分位数
        responseTimes.sort(Long::compareTo);
        int size = responseTimes.size();

        if (size > 0) {
            int p95Index = (int) Math.ceil(size * 0.95) - 1;
            int p99Index = (int) Math.ceil(size * 0.99) - 1;

            p95ResponseTime = responseTimes.get(Math.max(0, p95Index));
            p99ResponseTime = responseTimes.get(Math.max(0, p99Index));
        }
    }

    /**
     * 完成测试，计算最终统计
     */
    public void finishTest() {
        setTestEndTime(System.currentTimeMillis());

        // 计算QPS和TPS
        if (testDuration > 0) {
            qps = (double) totalRequests / (testDuration / 1000.0);
            tps = (double) successRequests / (testDuration / 1000.0);
        }

        updateResponseTimeStats();
    }

    @Override
    public String toString() {
        return "TestReport{" +
                "testName='" + testName + '\'' +
                ", totalRequests=" + totalRequests +
                ", successRate=" + String.format("%.2f", successRate) + "%" +
                ", avgResponseTime=" + String.format("%.2f", avgResponseTime) + "ms" +
                ", qps=" + String.format("%.2f", qps) +
                '}';
    }
}